Fix self-hosted checker and workflow routing#1976
Fix self-hosted checker and workflow routing#1976aiokaizen wants to merge 3 commits intoopenstatusHQ:mainfrom
Conversation
|
@aiokaizen is attempting to deploy a commit to the OpenStatus Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| } | ||
|
|
||
| func UpdateStatus(ctx context.Context, updateData UpdateData) error { | ||
|
|
There was a problem hiding this comment.
openstatus/apps/checker/cmd/server/main.go
Line 175 in 55f2e53
We should do something like this instead
|
Also for self host it's easier to use private location |
There was a problem hiding this comment.
Pull request overview
This PR fixes self-hosted deployments by decoupling checker/workflow routing from OpenStatus cloud infrastructure and disabling Cloud Tasks usage when GCP config isn’t present.
Changes:
- Added explicit self-host routing via env vars (checker/workflows base URLs + region) and updated API/server to call local checker endpoints.
- Updated workflows to avoid initializing/using Google Cloud Tasks in self-host mode or without valid GCP config, and added a direct HTTP dispatch path to the checker.
- Updated Docker Compose and env examples to include a Redis REST shim and self-host service wiring.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/api/src/router/checker.ts | Routes checker calls to local base URL in self-host mode and normalizes region/base URL handling. |
| apps/server/src/routes/v1/check/http/post.ts | Uses self-host checker routing for test runs instead of hosted Fly endpoints. |
| apps/server/src/libs/checker/utils.ts | Builds checker URLs pointing to local checker service in self-host mode. |
| apps/workflows/src/env.ts | Adds self-host routing env variables and SELF_HOST flag to workflows config. |
| apps/workflows/src/cron/monitor.ts | Lazily constructs Cloud Tasks context only when configured; skips lifecycle workflow scheduling if unavailable. |
| apps/workflows/src/cron/checker.ts | Adds direct (non-Cloud-Tasks) dispatch to checker for self-host / no-GCP configs. |
| apps/checker/checker/update.go | Posts status updates directly back to workflows in self-host/custom workflows URL mode. |
| docker-compose.yaml | Adds redis + redis-http services and wires new self-host env vars across services including checker. |
| docker-compose.github-packages.yaml | Same as above but for GitHub Packages images. |
| .env.docker.example | Updates env guidance for self-host routing and Redis REST shim defaults. |
| .env.docker-lightweight.example | Adds missing self-host routing + Redis REST shim variables. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| c: Context, | ||
| ) { | ||
| const timestamp = Date.now(); | ||
| const selfHostRegion = env().CHECKER_REGION as Region; |
| for (const row of monitors.data) { | ||
| const result = await db | ||
| .select() | ||
| .from(monitorStatusTable) | ||
| .where(eq(monitorStatusTable.monitorId, row.id)) | ||
| .all(); | ||
| const monitorStatus = z.array(selectMonitorStatusSchema).safeParse(result); |
| ); | ||
| } | ||
|
|
||
| const allRequests = await Promise.allSettled(allResult); |
| const selfHostRegion = env().CHECKER_REGION as Region; | ||
|
|
| const response = await fetch( | ||
| `${getCheckerBaseUrl()}/checker/${row.jobType}?monitor_id=${row.id}`, | ||
| { | ||
| method: "POST", | ||
| headers: { | ||
| Authorization: `Basic ${env().CRON_SECRET}`, | ||
| "Content-Type": "application/json", | ||
| }, | ||
| body: JSON.stringify(payload), | ||
| }, | ||
| ); |
| payloadBuf := new(bytes.Buffer) | ||
|
|
||
| if os.Getenv("SELF_HOST") == "true" || os.Getenv("OPENSTATUS_WORKFLOWS_URL") != "" { | ||
| if err := json.NewEncoder(payloadBuf).Encode(updateData); err != nil { | ||
| log.Ctx(ctx).Error().Err(err).Msg("error while encoding update payload") | ||
| return err | ||
| } | ||
|
|
||
| req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, payloadBuf) | ||
| if err != nil { | ||
| log.Ctx(ctx).Error().Err(err).Msg("error while creating update request") | ||
| return err | ||
| } | ||
| req.Header.Set("Authorization", basic) | ||
| req.Header.Set("Content-Type", "application/json") | ||
|
|
||
| res, err := http.DefaultClient.Do(req) | ||
| if err != nil { | ||
| log.Ctx(ctx).Error().Err(err).Msg("error while posting update status directly") | ||
| return err | ||
| } | ||
| defer res.Body.Close() | ||
|
|
||
| if res.StatusCode < 200 || res.StatusCode >= 300 { | ||
| return fmt.Errorf("direct updateStatus failed with status %d", res.StatusCode) | ||
| } | ||
|
|
||
| return nil | ||
| } |
| req.Header.Set("Authorization", basic) | ||
| req.Header.Set("Content-Type", "application/json") | ||
|
|
||
| res, err := http.DefaultClient.Do(req) |
| - "8079:80" | ||
| environment: | ||
| - SRH_MODE=env | ||
| - SRH_TOKEN=${UPSTASH_REDIS_REST_TOKEN:-replace-with-a-long-random-secret} |
| function isSelfHost() { | ||
| return process.env.SELF_HOST === "true"; | ||
| } | ||
|
|
||
| function getCheckerBaseUrl() { | ||
| return (process.env.CHECKER_BASE_URL || "http://checker:8080").replace( | ||
| /\/$/, | ||
| "", | ||
| ); | ||
| } | ||
|
|
||
| function getCheckerRegion(region: string) { |
…table. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
Hello team, We are currently on a tight schedule and are not able to continue addressing the remaining comments on this MR. For our immediate needs, we have moved to another solution. I did test this MR, and it appears to run correctly on our side, but we ran into other issues that we did not have time to investigate further. If someone from your team is able to take over the remaining review comments, that would be greatly appreciated. Otherwise, I may revisit them later if time allows. Thank you for your understanding. |
actually local.